package cn.com.spring.aspecti.impl;


import cn.com.spring.annotation.After;
import cn.com.spring.annotation.Around;
import cn.com.spring.annotation.Aspect;
import cn.com.spring.annotation.Before;
import cn.com.spring.annotation.Component;
import cn.com.spring.annotation.TimeConsumption;
import cn.com.spring.model.EntityInvocation;
import cn.com.utils.TimerCountUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * 生成异步代理
 *
 * @author LiuGuodong
 * @date 2023/01/28
 */
@Aspect
@Slf4j
@Component
public class CountHandler {

    @Before(name = TimeConsumption.class)
    public void Before() {
        log.info("TimeConsumption 拦截 {}", "Before");
    }

    @After(name = TimeConsumption.class)
    public void After() {
        log.info("TimeConsumption 拦截 {}", "After");
    }

    @Around(name = TimeConsumption.class)
    public Object execution(EntityInvocation entityInvocation) throws Throwable {
        log.info("TimeConsumption 拦截 {}", entityInvocation.getMethod().getName());
        Object result = null;
        TimeConsumption timeConsumption = entityInvocation.getMethod().getAnnotation(TimeConsumption.class);
        TimeUnit unit = timeConsumption.value();
        TimerCountUtil.start();
        result = entityInvocation.proceed();
        log.info("共耗时：{} {}", unit.convert(TimerCountUtil.stop(), TimeUnit.NANOSECONDS), unit);
        return result;
    }

    /**
     * 获得可调用
     *
     * @return {@link Callable}<{@link ?}>
     */
    private static Callable<?> getCallable(EntityInvocation entityInvocation) {
        return () -> {
            try {
                return entityInvocation.proceed();
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        };
    }

    /**
     * 可运行
     *
     * @return {@link Runnable}
     */
    private static Runnable getRunnable(EntityInvocation entityInvocation) {
        return () -> {
            try {
                entityInvocation.proceed();
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        };
    }


}
